//匹配{{}} 里面任意字符或 可换行 零次或一次
const reg = /\{\{((?:.|\r?\n)+?)\}\}/g;

//编译文本
export function compile(node, vm) {

  /**
   * console.log(node);
   * <input type="text" v-model="message">
   *   {{message}}
   * <div>
   *   名字：{{person.name}}
   *   年龄：{{person.age}}
   * </div>
   * <div>{{nums}}</div>
   */

  let childNodes = node.childNodes;
  // console.log(childNodes);
  //NodeList(7) [text, input, text, div, text, div, text]

  //类数组转为数组
  let childNodesArr = [...childNodes];
  // console.log(childNodesArr);
  //[text, input, text, div, text, div, text]

  //拿到每一个子节点
  childNodesArr.forEach(child => {
    if (child.nodeType === 1) {
      //证明是元素节点
      /**
       * console.log(child);
       * <input type="text" v-model="message">
       * <div>名字：{{person.name}}年龄：{{person.age}}</div>
       * <div>{{nums}}</div>
       */

      //元素节点会存在元素节点嵌套的情况，所有需要递归编译
      //再次递归可以将嵌套在里面的文本节点继续编译
      compile(child, vm);

      // compileElement(child, vm);

    } else if (child.nodeType === 3) {
      //证明是文本节点

      /**
       * console.log(child);
       * #text
       * {{message}}
       * #text
       * #text
       */

      compileText(child, vm);

    }
  });

}

//编译文本
export function compileText(node, vm) {
  if (!node.expr) {
    //缓存第一次进来的文本内容
    node.expr = node.textContent;
  }

  node.textContent = node.expr.replace(reg, function (...args) {

    /**
     * console.log(args);
     * [
     *   0: "{{message}}",
     *   1: "message"
     *   2: 5,
     *   3: "\n    {{message}}\n    ",
     *   length: 4
     * ]
     */

    //拿到{{}}里去除空格的内容
    //arg[1]恰好是data属性里的key属性名
    let key = trimSpace(args[1]);

    //拿到data数据里对应key属性的值 并返回出去
    return getValue(key, vm);
  });
}

//编译元素
export function compileElement(node, vm) {

}

//去除空格
export function trimSpace(str) {
  //匹配空格 替换为空字符
  return str.replace(/\s+/g, '');
}

//获取data数据里对应key属性的值
export function getValue(exp, vm) {
  //vm.person.name

  //console.log(exp);
  //person.name

  //问题：明显vm['person.name']这样的写法是无法访问属性值
  //实际访问写法应该是vm['person']['name']

  //解决：通过reduce方法完成
  //1.以 . 作为分隔符分割字符串
  let keys = exp.split('.');
  //console.log(keys);
  //['person', 'name']

  //2.整理写法
  return keys.reduce((prev, next) => {
    prev = prev[next];
    return prev;
  }, vm);
}